import { visualizer } from 'rollup-plugin-visualizer';
import { defineConfig, loadEnv, type UserConfig } from 'vite';
import vuetify from 'vite-plugin-vuetify';
// import checker from 'vite-plugin-checker';
import Vue from '@vitejs/plugin-vue';
import path from 'path';
import fs from 'fs';
import svgLoader from 'vite-svg-loader';
// import vsharp from "vite-plugin-vsharp"
// @ts-ignore
import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill';
// import { NodeModulesPolyfillPlugin } from '@esbuild-plugins/node-modules-polyfill'
// import rollupNodePolyFill from 'rollup-plugin-node-polyfills'
import nodePolyfills from 'rollup-plugin-polyfill-node';
import legacy from '@vitejs/plugin-legacy';

// https://vitejs.dev/config/
export default defineConfig(async ({ mode }): Promise<UserConfig> => {
  console.log('mode:', mode);

  const config: UserConfig = {
    // https://vitejs.dev/config/#base
    base: './',
    // Resolver
    resolve: {
      // https://vitejs.dev/config/#resolve-alias
      alias: {
        '@': path.resolve(__dirname, 'src'),
        assert: require.resolve('assert/'),
        crypto: require.resolve('crypto-browserify'),
        http: require.resolve('agent-base'),
        https: require.resolve('agent-base'),
        url: require.resolve('url/'),
        os: require.resolve('os-browserify/browser'),
        stream: require.resolve('stream-browserify'),
      },
    },
    // optimizeDeps: {
    //   esbuildOptions: {
    //     // Node.js global to browser globalThis
    //     define: {
    //       global: "globalThis",
    //     },
    //     // Enable esbuild polyfill plugins
    //     plugins: [
    //       NodeGlobalsPolyfillPlugin({
    //         process: true,
    //         buffer: true,
    //       }),
    //       // NodeModulesPolyfillPlugin()
    //     ],
    //   }
    // },
    // https://vitejs.dev/config/#server-options
    server: {
      host: '0.0.0.0',
      port: Number(loadEnv(mode, process.cwd()).VITE_APP_PORT),
      fs: {
        // Allow serving files from one level up to the project root
        allow: ['..'],
      },
    },
    plugins: [
      // Vue3
      Vue(),

      // Vuetify Loader
      // https://github.com/vuetifyjs/vuetify-loader
      vuetify({
        autoImport: true,
      }),

      // vite-plugin-checker
      // https://github.com/fi3ework/vite-plugin-checker
      // checker({typescript: true, vueTsc: true}),

      // compress assets
      // https://github.com/vbenjs/vite-plugin-compression
      // viteCompression(),

      // https://github.com/jpkleemans/vite-svg-loader
      svgLoader(),

      // vsharp()

      mode !== 'production' &&
      nodePolyfills({
        include: [
          'node_modules/**/*.js',
          new RegExp('node_modules/.vite/.*js'),
        ],
      }),

      legacy({
        targets: [
          'defaults',
          'not IE 11',
          'maintained node versions',
          'iOS >= 11.0',
          'chrome 52',
          // 'supports css-grid',
          // 'supports es6-module'
        ],
        additionalLegacyPolyfills: ['regenerator-runtime/runtime'],
        renderLegacyChunks: true,
        polyfills: [
          'es.symbol',
          'es.array.filter',
          'es.promise',
          'es.promise.finally',
          'es/map',
          'es/set',
          'es.array.for-each',
          'es.object.define-properties',
          'es.object.define-property',
          'es.object.get-own-property-descriptor',
          'es.object.get-own-property-descriptors',
          'es.object.keys',
          'es.object.to-string',
          'web.dom-collections.for-each',
          'esnext.global-this',
          'esnext.string.match-all',
        ],
      }),
    ],
    css: {
      preprocessorOptions: {
        scss: {
          additionalData: '@import "@/styles/global.scss";',
        },
      },
    },
    // Build Options
    // https://vitejs.dev/config/#build-options
    build: {
      rollupOptions: {
        output: {
          manualChunks: {
            // Split external library from transpiled code.
            vue: ['vue', 'vue-router', 'pinia', 'pinia-plugin-persist'],
            vuetify: [
              'vuetify',
              'vuetify/components',
              'vuetify/directives',
              'vuetify/lib/styles/main.css',
              'webfontloader',
            ],
            materialdesignicons: ['@mdi/font/css/materialdesignicons.css'],
          },
          plugins: [
            mode === 'analyze'
              ? // rollup-plugin-visualizer
              // https://github.com/btd/rollup-plugin-visualizer
              visualizer({
                open: true,
                filename: 'dist/stats.html',
                gzipSize: true,
                brotliSize: true,
              })
              : undefined,
            /*
            // if you use Code encryption by rollup-plugin-obfuscator
            // https://github.com/getkey/rollup-plugin-obfuscator
            obfuscator({
              globalOptions: {
                debugProtection: true,
              },
            }),
            */
          ],
        },
        plugins: [nodePolyfills()],
      },
      target: 'es2015',
      commonjsOptions: {
        transformMixedEsModules: true,
      },
      /*
      // Minify option
      // https://vitejs.dev/config/#build-minify
      minify: 'terser',
      terserOptions: {
        ecma: 2020,
        parse: {},
        compress: { drop_console: true },
        mangle: true, // Note `mangle.properties` is `false` by default.
        module: true,
        output: { comments: true, beautify: false },
      },
      */
    },
  };
  // Hook production build.
  // if (command === 'build') {
  // Write meta data.
  fs.writeFileSync(
    path.resolve(path.join(__dirname, 'src/Meta.ts')),
    `import type MetaInterface from '@/interfaces/MetaInterface';

// This file is auto-generated by the build system.
const meta: MetaInterface = {
  version: '${require('./package.json').version}',
  date: '${new Date().toISOString()}',
};
export default meta;
`
  );
  // }

  return config;
});
